import Flutter
import UIKit
import CoreTelephony

struct Contants {
  static let keyboardEventChannelName = "keyboard_visibility_event"
  static let keyboardIsHide = 0
  static let keyboardIsShow = 1
}

public class SwiftExtendedPlugin: NSObject, FlutterPlugin {
  public static func register(with registrar: FlutterPluginRegistrar) {
    let channel = FlutterMethodChannel(name: "extended_plugin", binaryMessenger: registrar.messenger())
    let instance = SwiftExtendedPlugin()
    registrar.addMethodCallDelegate(instance, channel: channel)
    
    let eventChannel = FlutterEventChannel(name: Contants.keyboardEventChannelName, binaryMessenger: registrar.messenger())
    eventChannel.setStreamHandler(KeyboardEventHandler())
  }

  public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
     if (call.method == "network_event") {

                let info: CTTelephonyNetworkInfo = CTTelephonyNetworkInfo()
                let carrier: CTCarrier = info.subscriberCellularProvider!
                let unknown: String = "unknown"


                if (carrier.mobileCountryCode!.hasPrefix("460")) {

                    let mobileCountryCode = carrier.mobileCountryCode ?? unknown
                    let mobileNetworkCode = carrier.mobileNetworkCode ?? unknown
                    let isoCountryCode = carrier.isoCountryCode ?? unknown
                    let carrierName = carrier.carrierName ?? unknown


                    if #available(iOS 12.0, *) {
                        let serviceCurrentRadioAccessTechnology: Dictionary = info.serviceCurrentRadioAccessTechnology ?? [unknown: unknown]
                        let sFirst:String = serviceCurrentRadioAccessTechnology.values.first ?? unknown


                        let carrierString = "\(mobileCountryCode)-\(mobileNetworkCode)-\(isoCountryCode)(\(carrierName)-\(sFirst)"

                        result(carrierString)

                    } else {
                        let currentRadioAccessTechnology: String = info.currentRadioAccessTechnology ?? unknown

                        let carrierString = "\(mobileCountryCode)-\(mobileNetworkCode)-\(isoCountryCode)(\(carrierName)-\(currentRadioAccessTechnology)"

                        result(carrierString)
                    }


                }


            }
  }

}

public class KeyboardEventHandler: NSObject, FlutterStreamHandler {
  var _eventSink: FlutterEventSink?
  var hasListener = false;
  var isVisble = false
  
  public override init() {
    super.init()
    NotificationCenter.default.addObserver(self,
                                           selector: #selector(willShow(_ :)),
                                           name: UIResponder.keyboardWillShowNotification,
                                           object: nil)
    
    NotificationCenter.default.addObserver(self,
                                           selector: #selector(didShow(_ :)),
                                           name: UIResponder.keyboardDidShowNotification,
                                           object: nil)

    NotificationCenter.default.addObserver(self,
                                           selector: #selector(didHide(_ :)),
                                           name: UIResponder.keyboardWillHideNotification,
                                           object: nil)
    
  }
  
  @objc func willShow(_ notification:Notification) {
    if (self.isVisble) {
      return ;
    }
    
    self.isVisble = true
    if (hasListener) {
      self._eventSink?(Contants.keyboardIsShow)
    }
  }
  
  @objc func didShow(_ notification:Notification) {
    if (self.isVisble) {
      return ;
    }
    
    self.isVisble = true
    if (hasListener) {
      self._eventSink?(Contants.keyboardIsShow)
    }

  }
  
  @objc func didHide(_ notification:Notification) {
    if (!self.isVisble) {
      return ;
    }
    
    self.isVisble = false
    if (hasListener) {
      self._eventSink?(Contants.keyboardIsHide)
    }
  }
  
  public func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? {
    self._eventSink = events
    self.hasListener = true
    
    return nil;
  }
  
  public func onCancel(withArguments arguments: Any?) -> FlutterError? {
    self._eventSink = nil
    self.hasListener = false
    return nil;
  }
}
